#include "sqldatadb.h"

#include <qDebug>
#include <QSqlQuery>
#include <QGuiApplication>

#include <QSqlRecord>
#include <QVariant>
#include <QBuffer>
#include <QPixmap>
#include <QFile>
#include <vector>
#include <QMutexLocker>
#include <QSqlError>
#include <QDataStream>
#include <QPicture>
#include <QPainter>
#include <iostream>
#include <QScopedPointer>
#include <QScopedPointer>
//#include <QPlatformPixmap>
#include <QImageWriter>
#include <QImageReader>
  #include   <string.h>
#include <malloc.h>
 #include "malloc.h"

#include <QString>
#include <osgDB/WriteFile>
#include <QDebug>
#include <TileKey.h>
#include <QDir>
#include <QColor>
#include <osgDB/ReadFile>
#include <QFile>
#include <QBitmap>
#include <QFile>
#include <QPixmapCache>
#include <QScopedPointer>
#include <QChar>
//#include <QPlatformPixmap>
#include <QImageIOHandler>
#include <QtWin>
#include <malloc.h>
#include <png.h>
#include  <pngconf.h>
//#include <pnginfo.h>
#include <pnglibconf.h>
#include <pngpriv.h>
#include <pngstruct.h>
#include <pngdebug.h>
#include "MYQPNGImageWriter.h"
#include <gdal_priv.h>
#include <gdal.h>

#include <stdlib.h>
 #include <sstream>
 #include <osg/Notify>
 #include <osg/Object>
 #include <osg/Image>
#include <osg/Node>
#include <osg/Group>
 #include <osg/Geode>
#include <osgDB/Registry>
#include <osgDB/WriteFile>
#include <osgDB/Options>
#include <osgDB/OutputStream>
#include <QMatrix>

//#include <DataOutputStream.h>
//#include ""
//#include <>
class osg::Image::DataIterator;

sqlDataDb::sqlDataDb()
{
//    //获取内存大小
//    int size =0;
//    MEMORYSTATUSEX memoryInfo;
//    memoryInfo.dwLength = sizeof(memoryInfo);
//    GlobalMemoryStatusEx(&memoryInfo);

//    int kb = 1024;
//    size = memoryInfo.ullTotalPhys/kb;
//    QPixmapCache::setCacheLimit(size);

}

void sqlDataDb::creatdb(QString name)
{
     m_db = QSqlDatabase::addDatabase("QSQLITE");
     m_db.setDatabaseName(name);
     if(!m_db.open())
     {
         qDebug()<<"数据库打开出错";
     }else
     {
         qDebug()<<"数据库打开成功";
     }

}
void sqlDataDb::creatAndroid_metadata()
{
    QSqlQuery       mquery;
    mquery = QSqlQuery(m_db);
    mquery.exec(QString("CREATE TABLE android_metadata(locale TEXT)"));
    mquery.exec(QString("INSERT INTO android_metadata VALUES ('zh_CN_#Hans')"));
}

void sqlDataDb::creattablesInfos()
{
    QSqlQuery       mquery;
    mquery = QSqlQuery(m_db);
    mquery.exec(QString("CREATE TABLE infos(minx double,miny double,maxx double, maxy double,minlevel int,maxlevel int,source VARCHAR(255),type VARCHAR(255),tiletrans VARCHAR(255),zip int,cur_level int,cur_x int,cur_y int,layerjson blob,contenttype VARCHAR(255))"));
}

void sqlDataDb::creatbackInfo(QString name)
{
    QSqlQuery       mquery;
    mquery = QSqlQuery(m_db);
    QString add=QString("create table '%1' (z int,x long,y long, tile blob)").arg(name);
    mquery.exec(add);

}

void sqlDataDb::addInfosinfo( TileServiceOption option, rxtiler::Extent ext, QString type)
{

   QSqlQuery       mquery;
   mquery = QSqlQuery(m_db);
   QString add=QString("insert into infos(minx ,miny ,maxx, maxy,minlevel,maxlevel,type,tiletrans,contenttype) values(:minx ,:miny ,:maxx, :maxy,:minlevel,:maxlevel,:type,:tiletrans,:contenttype)");

   mquery.prepare(add);
   if(type=="terrain")
   {
       double m_left = ext.left;
       double m_top = ext.bottom;
       double m_right = ext.right;
       double m_bottom = ext.top;

       if(m_left<-180)
       {
           m_left = -180;
       }
       if(m_top<-90)
       {
           m_top = -90;
       }
       if(m_right>180)
       {
           m_right =180;
       }
       if(m_bottom>90)
       {
           m_bottom = 90;
       }
       mquery.bindValue(":minx", m_left);
       mquery.bindValue(":miny", m_top);
       mquery.bindValue(":maxx", m_right);

       mquery.bindValue(":maxy", m_bottom);

   }

   mquery.bindValue(":minlevel", option.level0);
   mquery.bindValue(":maxlevel", option.level1);
   mquery.bindValue(":type",type);
   mquery.bindValue(":tiletrans", "tms");
   mquery.bindValue(":contenttype",type);
   mquery.exec();
}

void sqlDataDb::addInfosinfo(pakServiceOption option, Extent ext, QString type)
{
    QSqlQuery       mquery;
    mquery = QSqlQuery(m_db);
    QString add=QString("insert into infos(minx ,miny ,maxx, maxy,minlevel,maxlevel,type,tiletrans,contenttype) values(:minx ,:miny ,:maxx, :maxy,:minlevel,:maxlevel,:type,:tiletrans,:contenttype)");

    mquery.prepare(add);
    if(type=="WGS84")
    {
        double m_left = ext.left;
        double m_top = ext.bottom;
        double m_right = ext.right;
        double m_bottom = ext.top;

        if(m_left<-180)
        {
            m_left = -180;
        }
        if(m_top<-90)
        {
            m_top = -90;
        }
        if(m_right>180)
        {
            m_right =180;
        }
        if(m_bottom>90)
        {
            m_bottom = 90;
        }

        mquery.bindValue(":minx", m_left);
        mquery.bindValue(":miny", m_top);
        mquery.bindValue(":maxx", m_right);

        mquery.bindValue(":maxy", m_bottom);




    }else if(type=="WebMercator")
    {
        double m_left = ext.left;
        double m_top = ext.bottom;
        double m_right = ext.right;
        double m_bottom = ext.top;

        if(m_left<-180)
        {
            m_left = -180;
        }
        if(m_top<-85.05112878)
        {
            m_top = -85.05112878;
        }
        if(m_right>180)
        {
            m_right =180;
        }
        if(m_bottom>85.05112878)
        {
            m_bottom = 85.05112878;
        }

        mquery.bindValue(":minx", m_left);
        mquery.bindValue(":miny", m_top);
        mquery.bindValue(":maxx", m_right);

        mquery.bindValue(":maxy", m_bottom);

    }
    mquery.bindValue(":minlevel", option.level0);
    mquery.bindValue(":maxlevel", option.level1);
    mquery.bindValue(":type",type);
    mquery.bindValue(":tiletrans", "tms");
    mquery.bindValue(":contenttype",type);
    mquery.exec();
}


void sqlDataDb::addbacksinfo(QString name, TileKey key, osg::Image *img, QString imaform)
{
    QSqlQuery       mquery;
    mquery = QSqlQuery(m_db);
    QString add=QString("insert into %1(z, x, y, tile) values(:z, :x, :y, :tile)")\
            .arg(name);

    mquery.prepare(add);
    mquery.bindValue(":z", key.lod);
    mquery.bindValue(":x", key.x);
    mquery.bindValue(":y", key.y);
    QByteArray  imageArray;
    if(imaform =="png")
    {
        imageArray =  getimge(img);
    }
    mquery.bindValue(":tile", imageArray);
    if(!mquery.exec())
    {
        qDebug()<<"query exec error:"<<mquery.lastError().text();
    }
}

void sqlDataDb::addbacksinfoTerrain(QString name, TileKey key, osg::HeightField *dem, int demsize)
{
    QSqlQuery       mquery;
    mquery = QSqlQuery(m_db);
    QString add=QString("insert into %1(z, x, y, tile) values(:z, :x, :y, :tile)")\
            .arg(name);

    mquery.prepare(add);
    mquery.bindValue(":z", key.lod);
    mquery.bindValue(":x", key.x);
    mquery.bindValue(":y", key.y);
    QByteArray  imageArray;
    imageArray =  getTerrain(dem,demsize);

    mquery.bindValue(":tile", imageArray);
    if(!mquery.exec())
    {
        qDebug()<<"query exec error:"<<mquery.lastError().text();
    }
}
bool sqlDataDb::IsTableExist(QString name)
{
    QSqlQuery       mquery;
    mquery = QSqlQuery(m_db);
    QString sql = QString("select * from sqlite_master where name='%1'").arg(name);
    mquery.exec(sql);
    return mquery.next();
}

QByteArray sqlDataDb::getimge(osg::Image *img)
{
    QByteArray  imageArray;
    QBuffer *buffedr = new QBuffer();
    buffedr->open(QIODevice::WriteOnly);
    buffedr->seek(0);
    QScopedPointer<MYQPNGImageWriter>  m_ImageWriterr(new MYQPNGImageWriter()) ;;
    m_ImageWriterr.data()->setDevice(buffedr);
      m_ImageWriterr.data()->writeImage(img);
    imageArray= buffedr->data();
    return imageArray;
}

QByteArray sqlDataDb::getTerrain(osg::HeightField *dem, int demsize)
{
    QByteArray  imageArray;

//    int demsize = this->getTileSize();

    //向目录里存图片
    int fsize = demsize*demsize*sizeof(short)+2;
    short *s_dem = (short*)malloc(fsize);
    memset(s_dem,0,fsize);
    for( int y = 0; y < demsize; y++)
    {
        for(int x = 0; x < demsize; x++ )
        {
            float hv = dem->getHeight(x,demsize - 1 - y);

            s_dem[y*demsize+x] = (short)(hv + 1000) * 5;
        }
    }


    imageArray = QByteArray((char*)s_dem, fsize);
    free(s_dem);
    return imageArray;
}


QString sqlDataDb::settablename(TileKey key, int num)
{
       int tx = key.x/num;
       int ty = key.y/num;
       return "blacks_"+QString::number(key.lod)+"_"+QString::number(tx)+"_"+QString::number(ty);
}
void sqlDataDb::closedb()
{
    m_db.close();
}




















